from flask import Flask, request, jsonify, session, render_template_string, send_from_directory
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
import re
import os

app = Flask(__name__, static_folder='web', static_url_path='/static')
app.config['SECRET_KEY'] = 'your-secret-key-here'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///student_forms.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 配置CORS以解决跨域问题 - 允许常用的本地开发端口
CORS(app, 
     supports_credentials=True, 
     origins=[
         'http://localhost:3000',   # React
         'http://localhost:3001', 
         'http://localhost:4200',   # Angular
         'http://localhost:5000',   # Flask
         'http://localhost:8000',   # Django/其他
         'http://localhost:8080',   # Vue/其他
         'http://localhost:8081',
         'http://localhost:9000',
         'http://localhost:9001',
         'http://127.0.0.1:3000',
         'http://127.0.0.1:3001',
         'http://127.0.0.1:4200',
         'http://127.0.0.1:5000',
         'http://127.0.0.1:8000',
         'http://127.0.0.1:8080',
         'http://127.0.0.1:8081',
         'http://127.0.0.1:9000',
         'http://127.0.0.1:9001',
     ],
     allow_headers=['Content-Type', 'Authorization'],
     methods=['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'])

db = SQLAlchemy(app)

# 数据库模型
class StudentForm(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    phone = db.Column(db.String(20), nullable=False)
    grade = db.Column(db.Integer, nullable=False)
    age = db.Column(db.Integer, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

class Admin(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password_hash = db.Column(db.String(120), nullable=False)

# 表单验证函数
def validate_form_data(data):
    errors = []
    
    # 验证姓名
    if not data.get('name') or not data['name'].strip():
        errors.append('姓名不能为空')
    elif len(data['name'].strip()) < 2:
        errors.append('姓名至少需要2个字符')
    
    # 验证电话
    phone = data.get('phone', '').strip()
    if not phone:
        errors.append('电话号码不能为空')
    elif not re.match(r'^1[3-9]\d{9}$', phone):
        errors.append('请输入有效的手机号码')
    
    # 验证年级
    try:
        grade = int(data.get('grade', 0))
        if grade < 1 or grade > 12:
            errors.append('年级必须在1-12之间')
    except (ValueError, TypeError):
        errors.append('年级必须是数字')
    
    # 验证年龄
    try:
        age = int(data.get('age', 0))
        if age < 5 or age > 25:
            errors.append('年龄必须在5-25之间')
    except (ValueError, TypeError):
        errors.append('年龄必须是数字')
    
    return errors

# 静态文件服务
@app.route('/static/<path:filename>')
def serve_static(filename):
    """提供静态文件服务"""
    return send_from_directory('web', filename)

# Favicon 路由
@app.route('/favicon.ico')
def favicon():
    """提供favicon服务"""
    return send_from_directory('web', 'favicon.ico', mimetype='image/vnd.microsoft.icon')

# 前端页面路由
@app.route('/')
def index():
    """首页 - 学生表单提交页面"""
    with open('web/index.html', 'r', encoding='utf-8') as f:
        return f.read()

@app.route('/admin')
def admin():
    """后台管理页面"""
    with open('web/admin.html', 'r', encoding='utf-8') as f:
        content = f.read()
        return content

# 接口1：提交表单
@app.route('/api/submit-form', methods=['POST'])
def submit_form():
    """提交学生表单"""
    try:
        data = request.get_json()
        
        # 验证数据
        errors = validate_form_data(data)
        if errors:
            return jsonify({
                'success': False,
                'message': '表单验证失败',
                'errors': errors
            }), 400
        
        # 检查电话号码是否已存在
        existing_form = StudentForm.query.filter_by(phone=data['phone'].strip()).first()
        if existing_form:
            return jsonify({
                'success': False,
                'message': '该手机号码已经提交过表单'
            }), 400
        
        # 创建新的表单记录
        new_form = StudentForm(
            name=data['name'].strip(),
            phone=data['phone'].strip(),
            grade=int(data['grade']),
            age=int(data['age'])
        )
        
        db.session.add(new_form)
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '表单提交成功',
            'data': {
                'id': new_form.id,
                'name': new_form.name,
                'phone': new_form.phone,
                'grade': new_form.grade,
                'age': new_form.age,
                'created_at': new_form.created_at.strftime('%Y-%m-%d %H:%M:%S')
            }
        }), 201
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': '服务器内部错误'
        }), 500

# 接口2：管理员登录
@app.route('/api/admin/login', methods=['POST'])
def admin_login():
    """管理员登录"""
    try:
        data = request.get_json()
        username = data.get('username', '').strip()
        password = data.get('password', '')
        
        if not username or not password:
            return jsonify({
                'success': False,
                'message': '用户名和密码不能为空'
            }), 400
        
        admin = Admin.query.filter_by(username=username).first()
        
        if admin and check_password_hash(admin.password_hash, password):
            session['admin_id'] = admin.id
            session['admin_username'] = admin.username
            return jsonify({
                'success': True,
                'message': '登录成功',
                'data': {
                    'username': admin.username
                }
            }), 200
        else:
            return jsonify({
                'success': False,
                'message': '用户名或密码错误'
            }), 401
            
    except Exception as e:
        return jsonify({
            'success': False,
            'message': '服务器内部错误'
        }), 500

# 接口3：查看提交列表（需要管理员登录）
@app.route('/api/admin/forms', methods=['GET'])
def get_forms():
    """获取表单提交列表（需要管理员登录）"""
    try:
        # 检查管理员是否已登录
        if 'admin_id' not in session:
            return jsonify({
                'success': False,
                'message': '请先登录'
            }), 401
        
        # 获取分页参数
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        
        # 查询表单数据
        forms = StudentForm.query.order_by(StudentForm.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        form_list = []
        for form in forms.items:
            form_list.append({
                'id': form.id,
                'name': form.name,
                'phone': form.phone,
                'grade': form.grade,
                'age': form.age,
                'created_at': form.created_at.strftime('%Y-%m-%d %H:%M:%S')
            })
        
        return jsonify({
            'success': True,
            'message': '获取成功',
            'data': {
                'forms': form_list,
                'pagination': {
                    'page': forms.page,
                    'pages': forms.pages,
                    'per_page': forms.per_page,
                    'total': forms.total,
                    'has_next': forms.has_next,
                    'has_prev': forms.has_prev
                }
            }
        }), 200
        
    except Exception as e:
        return jsonify({
            'success': False,
            'message': '服务器内部错误'
        }), 500

# 检查登录状态接口
@app.route('/api/admin/status', methods=['GET'])
def admin_status():
    """检查管理员登录状态"""
    if 'admin_id' in session:
        return jsonify({
            'success': True,
            'message': '已登录',
            'data': {
                'username': session.get('admin_username'),
                'logged_in': True
            }
        }), 200
    else:
        return jsonify({
            'success': False,
            'message': '未登录',
            'data': {
                'logged_in': False
            }
        }), 401

# 管理员登出接口
@app.route('/api/admin/logout', methods=['POST'])
def admin_logout():
    """管理员登出"""
    session.pop('admin_id', None)
    session.pop('admin_username', None)
    return jsonify({
        'success': True,
        'message': '登出成功'
    }), 200

# 接口4：修改管理员密码
@app.route('/api/admin/change-password', methods=['POST'])
def change_password():
    """修改当前登录管理员的密码"""
    try:
        if 'admin_id' not in session:
            return jsonify({'success': False, 'message': '请先登录'}), 401

        data = request.get_json()
        old_password = data.get('old_password')
        new_password = data.get('new_password')
        confirm_password = data.get('confirm_password')

        if not all([old_password, new_password, confirm_password]):
            return jsonify({'success': False, 'message': '所有字段均为必填项'}), 400

        if new_password != confirm_password:
            return jsonify({'success': False, 'message': '新密码和确认密码不匹配'}), 400
        
        if len(new_password) < 6:
            return jsonify({'success': False, 'message': '新密码长度至少为6位'}), 400

        admin = Admin.query.get(session['admin_id'])
        if not admin or not check_password_hash(admin.password_hash, old_password):
            return jsonify({'success': False, 'message': '旧密码不正确'}), 401
        
        admin.password_hash = generate_password_hash(new_password)
        db.session.commit()

        return jsonify({'success': True, 'message': '密码修改成功，请重新登录'}), 200

    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': '服务器内部错误'}), 500

# Swagger UI 模板
SWAGGER_TEMPLATE = '''
<!DOCTYPE html>
<html>
<head>
    <title>学生表单提交系统 API 文档</title>
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.25.0/swagger-ui.css" />
    <style>
        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }
        *, *:before, *:after {
            box-sizing: inherit;
        }
        body {
            margin:0;
            background: #fafafa;
        }
    </style>
</head>
<body>
    <div id="swagger-ui"></div>
    <script src="https://unpkg.com/swagger-ui-dist@3.25.0/swagger-ui-bundle.js"></script>
    <script src="https://unpkg.com/swagger-ui-dist@3.25.0/swagger-ui-standalone-preset.js"></script>
    <script>
        window.onload = function() {
            const ui = SwaggerUIBundle({
                url: '/api/swagger.json',
                dom_id: '#swagger-ui',
                deepLinking: true,
                presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIStandalonePreset
                ],
                plugins: [
                    SwaggerUIBundle.plugins.DownloadUrl
                ],
                layout: "StandaloneLayout"
            });
        };
    </script>
</body>
</html>
'''

# Swagger JSON 配置
@app.route('/api/swagger.json')
def swagger_json():
    return jsonify({
        "openapi": "3.0.0",
        "info": {
            "title": "学生表单提交系统 API",
            "description": "一个包含表单提交、管理员登录和数据查看的后端服务系统",
            "version": "1.0.0"
        },
        "servers": [
            {
                "url": "http://localhost:5000",
                "description": "开发服务器"
            }
        ],
        "paths": {
            "/api/submit-form": {
                "post": {
                    "tags": ["表单管理"],
                    "summary": "提交学生表单",
                    "description": "提交包含学生姓名、电话、年级、年龄的表单信息",
                    "requestBody": {
                        "required": True,
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": ["name", "phone", "grade", "age"],
                                    "properties": {
                                        "name": {
                                            "type": "string",
                                            "description": "学生姓名",
                                            "example": "张三",
                                            "minLength": 2
                                        },
                                        "phone": {
                                            "type": "string",
                                            "description": "手机号码",
                                            "example": "13800138000",
                                            "pattern": "^1[3-9]\\d{9}$"
                                        },
                                        "grade": {
                                            "type": "integer",
                                            "description": "年级 (1-12)",
                                            "example": 9,
                                            "minimum": 1,
                                            "maximum": 12
                                        },
                                        "age": {
                                            "type": "integer",
                                            "description": "年龄 (5-25)",
                                            "example": 15,
                                            "minimum": 5,
                                            "maximum": 25
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "responses": {
                        "201": {
                            "description": "表单提交成功",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/SuccessResponse"
                                    }
                                }
                            }
                        },
                        "400": {
                            "description": "表单验证失败",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/ErrorResponse"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "/api/admin/login": {
                "post": {
                    "tags": ["管理员管理"],
                    "summary": "管理员登录",
                    "description": "管理员使用用户名和密码登录系统",
                    "requestBody": {
                        "required": True,
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": ["username", "password"],
                                    "properties": {
                                        "username": {
                                            "type": "string",
                                            "description": "管理员用户名",
                                            "example": "admin"
                                        },
                                        "password": {
                                            "type": "string",
                                            "description": "管理员密码",
                                            "example": "admin123"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "responses": {
                        "200": {
                            "description": "登录成功",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/SuccessResponse"
                                    }
                                }
                            }
                        },
                        "401": {
                            "description": "用户名或密码错误",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/ErrorResponse"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "/api/admin/status": {
                "get": {
                    "tags": ["管理员管理"],
                    "summary": "检查登录状态",
                    "description": "检查管理员是否已登录",
                    "responses": {
                        "200": {
                            "description": "已登录",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/SuccessResponse"
                                    }
                                }
                            }
                        },
                        "401": {
                            "description": "未登录",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/ErrorResponse"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "/api/admin/forms": {
                "get": {
                    "tags": ["管理员管理"],
                    "summary": "获取表单提交列表",
                    "description": "获取所有学生表单提交记录，支持分页（需要管理员登录）",
                    "parameters": [
                        {
                            "name": "page",
                            "in": "query",
                            "description": "页码",
                            "schema": {
                                "type": "integer",
                                "default": 1,
                                "minimum": 1
                            }
                        },
                        {
                            "name": "per_page",
                            "in": "query",
                            "description": "每页数量",
                            "schema": {
                                "type": "integer",
                                "default": 10,
                                "minimum": 1,
                                "maximum": 100
                            }
                        }
                    ],
                    "responses": {
                        "200": {
                            "description": "获取成功",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/FormsResponse"
                                    }
                                }
                            }
                        },
                        "401": {
                            "description": "未登录",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/ErrorResponse"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "/api/admin/logout": {
                "post": {
                    "tags": ["管理员管理"],
                    "summary": "管理员登出",
                    "description": "管理员退出登录",
                    "responses": {
                        "200": {
                            "description": "登出成功",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "$ref": "#/components/schemas/SuccessResponse"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "components": {
            "schemas": {
                "SuccessResponse": {
                    "type": "object",
                    "properties": {
                        "success": {
                            "type": "boolean",
                            "example": True
                        },
                        "message": {
                            "type": "string",
                            "example": "操作成功"
                        },
                        "data": {
                            "type": "object",
                            "description": "响应数据"
                        }
                    }
                },
                "ErrorResponse": {
                    "type": "object",
                    "properties": {
                        "success": {
                            "type": "boolean",
                            "example": False
                        },
                        "message": {
                            "type": "string",
                            "example": "操作失败"
                        },
                        "errors": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            },
                            "description": "错误信息列表"
                        }
                    }
                },
                "FormsResponse": {
                    "type": "object",
                    "properties": {
                        "success": {
                            "type": "boolean",
                            "example": True
                        },
                        "message": {
                            "type": "string",
                            "example": "获取成功"
                        },
                        "data": {
                            "type": "object",
                            "properties": {
                                "forms": {
                                    "type": "array",
                                    "items": {
                                        "type": "object",
                                        "properties": {
                                            "id": {"type": "integer"},
                                            "name": {"type": "string"},
                                            "phone": {"type": "string"},
                                            "grade": {"type": "integer"},
                                            "age": {"type": "integer"},
                                            "created_at": {"type": "string"}
                                        }
                                    }
                                },
                                "pagination": {
                                    "type": "object",
                                    "properties": {
                                        "page": {"type": "integer"},
                                        "pages": {"type": "integer"},
                                        "per_page": {"type": "integer"},
                                        "total": {"type": "integer"},
                                        "has_next": {"type": "boolean"},
                                        "has_prev": {"type": "boolean"}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    })

# Swagger UI 页面
@app.route('/docs/')
@app.route('/docs')
def swagger_ui():
    return render_template_string(SWAGGER_TEMPLATE)

# 数据库初始化CLI命令
@app.cli.command("init-db")
def init_db_command():
    """创建数据库表和默认管理员账户"""
    with app.app_context():
        db.create_all()
        if not Admin.query.filter_by(username='admin').first():
            admin = Admin(
                username='admin',
                password_hash=generate_password_hash('admin123')
            )
            db.session.add(admin)
            db.session.commit()
            print("数据库和默认管理员账户已成功创建。")
        else:
            print("数据库已存在，无需重复初始化。")

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)
